#include "EntityManager.h"
#include "GameGlobals.h"
#include "InputHandler.h"
#include "Utility.h"

EntityManager* Inst = NULL;

EntityManager* EntityManager::Instance()
{
	if (Inst == NULL)
	{
		Inst = new EntityManager;
	}
	return Inst;
}

EntityManager::EntityManager(void)
{
	NewEntityID = 0;
	CurrentTime = double(CurTime.GetElapsedTime()) / 100;
	LastThink = 0.0;
	Delta = 1 / 60.0;
}

EntityManager::~EntityManager(void)
{
	delete Entities;
	delete Physics;
	delete GameRules;
}

void EntityManager::Init()
{
	Entities = new EntityList();
	Physics = new PhysicsManager();
	GameRules = new GameLogic();
	GameRules->Initialize();
}

void EntityManager::Tick()
{
	double NewTime = double(CurTime.GetElapsedTime()) / 1000;

	GameGlobals::Instance()->CurTime = NewTime;

	std::list<BaseEntity*>::iterator i;

	if (LastThink + Delta < NewTime)
	{
		i = Entities->mList.begin();
		Physics->Tick();
		GameRules->Tick();
		while (i != Entities->mList.end())
		{
			BaseEntity *ent = *i;
			if (ent->DeleteMe == true)
			{
				GameRules->OnEntityDestroyed(ent);
				if (ent->GetPhysicsEnabled())
					Physics->RemoveEntity(ent);
				i = Entities->mList.erase(i);
				GameGlobals::Instance()->EntityCount = Entities->GetEntCount();
			}
			else
			{
				ent->Tick();
				i++;
			}
		}
		double frameTime = NewTime - CurrentTime;
		CurrentTime = NewTime;
		GameGlobals::Instance()->FrameTime = std::min(float(frameTime), 1/20.f);
		LastThink = NewTime;
	}
	i = Entities->mList.begin();
	while (i != Entities->mList.end())
	{
		BaseEntity *ent = *i;
		ent->Draw();
		i++;
	}
	sf::View CamView = pRender->GetView();
	pRender->SetView(pRender->GetDefaultView());
	GameRules->DrawHUD(pRender);
	pRender->SetView(CamView);
}

BaseEntity* EntityManager::CreateEntity(std::string ID)
{
	BaseEntity* ent = FactoryMap[ID]->Create(pRender);
	ent->ID = NewEntityID;
	NewEntityID++;
	ent->ClassName = ID;
	ent->pRender = pRender;
	Entities->AddToList(ent);
	if (ent->GetPhysicsEnabled())
	{
		Physics->RegisterPhysicsEntity(ent);
	}
	GameGlobals::Instance()->EntityCount = Entities->GetEntCount();
	GameRules->OnEntityCreated(ent);
	return ent;
}

void EntityManager::RegisterEntity(std::string Name, BaseFactory* Factory)
{
	std::cout << "Registering: " << Name << "\n";
	FactoryMap[Name] = Factory;
}

void EntityManager::FindByClass(std::string classname, std::vector<BaseEntity*> &vec)
{
	vec.clear();
	std::list<BaseEntity*>::iterator i;
	i = Entities->mList.begin();
	while (i != Entities->mList.end())
	{
		BaseEntity *ent = *i;
		if (ent->GetClassName() == classname)
		{
			vec.push_back(ent);
		}
		i++;
	}
}